package com.ruoyi.system.controller;

import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.web.page.TableDataInfo;
import com.ruoyi.system.domain.OutapiClientApiRel;
import com.ruoyi.system.domain.OutapiClientConfig;
import com.ruoyi.system.domain.OutapiInfo;
import com.ruoyi.system.domain.OutapiVisitLog;
import com.ruoyi.system.domain.vo.OutapiAppVo;
import com.ruoyi.system.domain.vo.OutapiServiceVo;
import com.ruoyi.system.domain.vo.OutapiTop5Vo;
import com.ruoyi.system.service.IOutapiClientApiRelService;
import com.ruoyi.system.service.IOutapiClientConfigService;
import com.ruoyi.system.service.IOutapiInfoService;
import com.ruoyi.system.service.IOutapiVisitLogService;
import com.ruoyi.system.util.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 服务监控
 *
 * @author wjialong
 */
@RestController
@RequestMapping("/outapi/monitor")
public class OutapiMonitorController extends BaseController {
    @Autowired
    IOutapiInfoService infoService;

    @Autowired
    IOutapiClientConfigService clientConfigService;

    @Autowired
    IOutapiClientApiRelService relService;

    @Autowired
    IOutapiVisitLogService logService;

    /**
     * 图表第一部分 - 服务总数..
     *
     * @return
     */
    @GetMapping("/service")
    public AjaxResult getServiceData() {
        Map<String, Object> resultMap = new HashMap<>();

        OutapiInfo info = new OutapiInfo();
        // 获取总服务数
        resultMap.put("total", infoService.selectOutapiInfoCount(info));
        // 获取发布服务数
        info.setApiStatus("1");
        resultMap.put("online", infoService.selectOutapiInfoCount(info));
        // 获取下线服务数
        info.setApiStatus("2");
        resultMap.put("outline", infoService.selectOutapiInfoCount(info));
        // 获取调用总数
        resultMap.put("logCount", logService.selectOutapiVisitLogCount(null));
        // 计算平均耗时
        resultMap.put("time", logService.getAvgExecuteTime(null).intValue());

        return AjaxResult.success(resultMap);
    }

    /**
     * 图表第二部分 - 应用总数
     *
     * @return
     */
    @GetMapping("/app")
    public AjaxResult getAppData() {
        Map<String, Object> resultMap = new HashMap<>();

        // 获取应用总数
        OutapiClientConfig clientConfig = new OutapiClientConfig();
        resultMap.put("appCount", clientConfigService.selectOutapiClientConfigCount(clientConfig));
        // 获取授权接口
        List<String> list = relService.selectClientApiList();
        resultMap.put("apiCount", list.size());
        // 获取成功率
        OutapiVisitLog log = new OutapiVisitLog();
        Integer all = 0;
        Integer success = 0;
        for (String i : list) {
            log.setRequestId(i);
            log.setSuccess(null);
            all += logService.selectOutapiVisitLogCount(log);
            log.setSuccess(1);
            success += logService.selectOutapiVisitLogCount(log);
        }
        Double d = all == 0 ? 0D : (success.doubleValue() / all);
        resultMap.put("success", String.format("%.4f", d));

        return AjaxResult.success(resultMap);
    }

    /**
     * 调用量统计接口
     *
     * @param startTime
     * @param endTime
     * @return
     */
    @GetMapping("/usageChart")
    public AjaxResult getChartData(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
                                   @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
        Map<String, Object> resultMap = new HashMap<>();
        OutapiVisitLog log = new OutapiVisitLog();
        List<String> dayList = new ArrayList<>(7);
        List<Integer> successList = new ArrayList<>(7);
        List<Integer> failList = new ArrayList<>(7);
        LocalDateTime curTime = startTime;

        while (curTime.isBefore(endTime)) {
            dayList.add(curTime.format(DateTimeFormatter.ofPattern("MM-dd")));
            log.setCreateTime(DateUtils.asDate(curTime));
            log.setSuccess(1);
            successList.add(logService.selectOutapiVisitLogCount(log));
            log.setSuccess(0);
            failList.add(logService.selectOutapiVisitLogCount(log));
            curTime = curTime.plusDays(1);
        }

        resultMap.put("dayList", dayList);
        resultMap.put("successList", successList);
        resultMap.put("failList", failList);

        return AjaxResult.success(resultMap);
    }

    /**
     * 执行数top5统计
     *
     * @return
     */
    @GetMapping("/top5Chart")
    public AjaxResult getTop5Chart() {
        // 设置返回格式
        Map<String, Object> resultMap = new HashMap<>();
        List<String> serviceNameList = new ArrayList<>(5);
        List<Integer> serviceCountList = new ArrayList<>(5);
        List<String> appNameList = new ArrayList<>(5);
        List<Integer> appCountList = new ArrayList<>(5);
        // 进行查询
        List<OutapiTop5Vo> top5ServiceVo = logService.getTop5ServiceVo();
        List<OutapiTop5Vo> top5AppVo = logService.getTop5AppVo();
        for (OutapiTop5Vo vo : top5ServiceVo) {
            serviceNameList.add(vo.getName());
            serviceCountList.add(vo.getCount());
        }
        for (OutapiTop5Vo vo : top5AppVo) {
            appNameList.add(vo.getName());
            appCountList.add(vo.getCount());
        }
        // 返回数据
        resultMap.put("serviceNameList", serviceNameList);
        resultMap.put("serviceCountList", serviceCountList);
        resultMap.put("appNameList", appNameList);
        resultMap.put("appCountList", appCountList);
        return AjaxResult.success(resultMap);
    }

    /**
     * 服务监控列表获取
     *
     * @param outapiInfo
     * @param maxTime
     * @param minTime
     * @return
     */
    @GetMapping("/service/list")
    public TableDataInfo getServiceList(OutapiInfo outapiInfo,
                                        Double maxTime, Double minTime) {
        // 获取数据并自动分页
        startPage();
        List<OutapiServiceVo> outapiServiceVos = infoService.selectOutapiServiceVoList(outapiInfo, maxTime, minTime);
        // 添加执行次数和成功率数据
        OutapiVisitLog log = new OutapiVisitLog();
        for (OutapiServiceVo vo : outapiServiceVos) {
            Integer totalCount = 0;
            String success = "0";
            if (vo.getAvgTime() != null) {
                log.setSuccess(null);
                log.setRequestId(vo.getRequestId());
                totalCount = logService.selectOutapiVisitLogCount(log);
                log.setSuccess(1);
                Integer successCount = logService.selectOutapiVisitLogCount(log);
                success = String.format("%.4f", successCount.doubleValue() / totalCount);
            } else {
                vo.setAvgTime(0D);
                vo.setMaxTime(0D);
                vo.setMinTime(0D);
            }

            vo.setExecuteCount(totalCount);
            vo.setSuccess(success);
        }
        return getDataTable(outapiServiceVos);
    }

    @GetMapping("/app/list")
    public TableDataInfo getAppList(OutapiClientConfig outapiClientConfig,
                                    Double maxTime, Double minTime) {
        startPage();
        OutapiVisitLog log = new OutapiVisitLog();
        List<OutapiAppVo> outapiAppVos = clientConfigService.selectOutapiAppVoList(outapiClientConfig, maxTime, minTime);
        // 添加执行次数和成功率数据
        for (OutapiAppVo vo : outapiAppVos) {
            // 获取apiCount
            OutapiClientApiRel rel = new OutapiClientApiRel();
            rel.setConfigId(vo.getId());
            Integer apiCount = relService.selectOutapiRelCount(rel);
            // 获取app的执行次数
            Integer totalCount;
            String success;
            log.setClientId(vo.getId());
            log.setSuccess(null);
            totalCount = logService.selectOutapiVisitLogCount(log);
            // app不存在调用日志
            if (totalCount == 0) {
                vo.setAvgTime(0D);
                success = "0.0000";
            } else {
                log.setSuccess(1);
                Integer successCount = logService.selectOutapiVisitLogCount(log);
                success = String.format("%.4f", successCount.doubleValue() / totalCount);
            }

            vo.setApiCount(apiCount);
            vo.setExecuteCount(totalCount);
            vo.setSuccess(success);
        }
        return getDataTable(outapiAppVos);
    }

    @GetMapping("/api")
    public TableDataInfo getApiList(String id) {
        startPage();
        List<OutapiServiceVo> apiList = infoService.getApiListByAppId(id);
        for (OutapiServiceVo vo : apiList) {
            if (vo.getAvgTime() == null) {
                vo.setExecuteCount(0);
                vo.setAvgTime(0D);
            }
        }
        return getDataTable(apiList);
    }

}
